package oop.core;

import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

import oop.core.control.Controller;
import oop.core.entity.EntityLibrary;
import oop.core.entity.OccupationLibrary;
import oop.core.view.AreaPanel;
import oop.core.view.CharacterCreationMenu;
import oop.core.view.ControllerConfigMenu;
import oop.core.view.EquipmentPanel;
import oop.core.view.GamePanel;
import oop.core.view.ImageHandler;
import oop.core.view.InventoryPanel;
import oop.core.view.MainFrame;
import oop.core.view.MainMenu;
import oop.core.view.MainPanel;
import oop.core.view.SizeablePanel;
import oop.core.view.SkillsPanel;
import oop.core.view.StatsPanel;
import oop.core.view.Terminal;
import oop.core.view.listeners.AcceptControllerConfigListener;
import oop.core.view.listeners.ActiveSkillMouseListener;
import oop.core.view.listeners.EquipmentMouseListener;
import oop.core.view.listeners.InventoryMouseListener;
import oop.core.view.listeners.ToMainMenuListener;
import oop.core.view.listeners.ExitGameListener;
import oop.core.view.listeners.LoadControllerConfigListener;
import oop.core.view.listeners.NewGameListener;
import oop.core.view.listeners.ResetControllerConfigListener;
import oop.core.view.listeners.SaveControllerConfigListener;
import oop.core.view.listeners.ToCharacterCreationMenuListener;
import oop.core.view.listeners.ToControllerConfigMenuListener;

public class RunGame {

	private static MainPanel mainPanel;
	private static Terminal terminal;
	
	private Controller controller;
	
	private MainFrame mainFrame;
	
	private MainMenu mainMenu;
	private CharacterCreationMenu characterCreationMenu;
	private ControllerConfigMenu controllerConfigMenu;
	private GamePanel gamePanel;
	
	private AreaPanel areaPanel;
	private StatsPanel statsPanel;
	private SkillsPanel skillsPanel;
	private InventoryPanel inventoryPanel;
	private EquipmentPanel equipmentPanel;
	
	private ActionListener exitGameListener;
	private ActionListener newGameListener;
	
	private ActionListener toMainMenuListener;
	private ActionListener toCharacterCreationMenuListener;
	private ActionListener toControllerConfigMenuListener;
	
	private ActionListener acceptControllerConfigListener;
	private ActionListener saveControllerConfigListener;
	private ActionListener loadControllerConfigListener;
	private ActionListener resetControllerConfigListener;
	
	private MouseListener inventoryMouseListener;
	private MouseListener equipmentMouseListener;
	private MouseListener activeSkillMouseListener;
	
	public static void main(String[] args)
	{
		System.out.println("Starting main.");
		RunGame runGame = new RunGame();
		runGame.go();
		System.out.println("Exiting main.");
	}
	
	/**
	 * Initializes everything and starts at the main menu.
	 * @throws InterruptedException 
	 */
	private void go()
	{
		// Get graphics stuff
		GraphicsEnvironment graphEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
		GraphicsDevice graphDevice = graphEnv.getDefaultScreenDevice();
		GraphicsConfiguration graphicConf = graphDevice.getDefaultConfiguration();


		// Create controller, keyboard interpreter, etc.
		OccupationLibrary.init();
		ImageHandler.loadImages();
		EntityLibrary.init();
		
		controller = new Controller();
		
		
		// Create the GUI components
		mainFrame = new MainFrame(graphicConf);
		mainPanel = new MainPanel();

		mainMenu = new MainMenu();
		characterCreationMenu = new CharacterCreationMenu();
		
		areaPanel = new AreaPanel();
		statsPanel = new StatsPanel();
		skillsPanel = new SkillsPanel();
		inventoryPanel = new InventoryPanel();
		equipmentPanel = new EquipmentPanel();
		terminal = new Terminal();
		gamePanel = new GamePanel(areaPanel, statsPanel, skillsPanel, inventoryPanel, equipmentPanel, terminal);
		
		List<SizeablePanel> panels = new ArrayList<SizeablePanel>();
		panels.add(areaPanel);
		panels.add(statsPanel);
		panels.add(skillsPanel);
		panels.add(inventoryPanel);
		panels.add(equipmentPanel);

		controllerConfigMenu = new ControllerConfigMenu();

		mainFrame.add(mainPanel);
		mainPanel.add(mainMenu, MainMenu.ID);
		mainPanel.add(characterCreationMenu, CharacterCreationMenu.ID);
		mainPanel.add(controllerConfigMenu, ControllerConfigMenu.ID);
		mainPanel.add(gamePanel, GamePanel.ID);
	
		// Create listeners
		toMainMenuListener = new ToMainMenuListener();
		exitGameListener = new ExitGameListener();
		
		toCharacterCreationMenuListener = new ToCharacterCreationMenuListener();
		toControllerConfigMenuListener = new ToControllerConfigMenuListener();
		acceptControllerConfigListener = new AcceptControllerConfigListener(controller,controllerConfigMenu);
		saveControllerConfigListener = new SaveControllerConfigListener(controllerConfigMenu);
		loadControllerConfigListener = new LoadControllerConfigListener(controllerConfigMenu);
		resetControllerConfigListener = new ResetControllerConfigListener(controllerConfigMenu);
		
		inventoryMouseListener = new InventoryMouseListener();
		equipmentMouseListener = new EquipmentMouseListener();
		activeSkillMouseListener = new ActiveSkillMouseListener();
		
		
		// Make newGameListener
		newGameListener = new NewGameListener(gamePanel, areaPanel, statsPanel, skillsPanel, inventoryPanel, equipmentPanel, controller,
												(InventoryMouseListener)inventoryMouseListener, (EquipmentMouseListener)equipmentMouseListener,
												(ActiveSkillMouseListener)activeSkillMouseListener);
		
		// Add listeners to panels
		mainMenu.addNewGameButtonListener(toCharacterCreationMenuListener);
		mainMenu.addControllerConfigButtonListener(toControllerConfigMenuListener);
		mainMenu.addExitButtonListener(exitGameListener);
		
		characterCreationMenu.addButtonListeners(newGameListener);
		characterCreationMenu.addBackButtonListener(toMainMenuListener);

		controllerConfigMenu.addAcceptButtonListener(acceptControllerConfigListener);
		controllerConfigMenu.addSaveButtonListener(saveControllerConfigListener);
		controllerConfigMenu.addLoadButtonListener(loadControllerConfigListener);
		controllerConfigMenu.addResetButtonListener(resetControllerConfigListener);
		controllerConfigMenu.addCancelButtonListener(toMainMenuListener); //since this is the only functionality of it
		
		inventoryPanel.addMouseListener(inventoryMouseListener);
		equipmentPanel.addMouseListener(equipmentMouseListener);
		skillsPanel.addMouseListener(activeSkillMouseListener);
		mainPanel.addKeyListener(controller);	// TODO: Change panel/frame this gets added to
		
//		mainPanel.repaint();
		RunGame.changePanel(MainMenu.ID);
//		mainFrame.repaint();
	}
	
	public static void changePanel(String name)
	{
		mainPanel.changePanel(name);
	}
	
	public static void println(String text)
	{
		terminal.appendln(text);
	}
	
	public static void print(String text)
	{
		terminal.append(text);
	}
	
	public static void printMatrix()
	{
		terminal.printMatrix();
	}
	
	public static void endGame()
	{
		JOptionPane.showMessageDialog(null, "GAME OVER!");
		RunGame.changePanel(MainMenu.ID);
	}
	
}
